package com.lmx.cloud;


import com.lmx.bean.FileUnit;
import com.lmx.control.WlanManager;
import com.lmx.creceive.receive;
import com.lmx.util.LogUtil;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.NoRouteToHostException;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Objects;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import org.glassfish.grizzly.threadpool.FixedThreadPool;

// 文件上传的队列，作用是自动从文件夹获取文件，然后上传，上传成功即删除，它的上传是通过调用FileUploader实现的
public class FileUploadQueue {
    private static Queue<int[]>queue;
    private static final HashSet<FileUnit> files = new HashSet<>();
    private static final AtomicBoolean enableUpload = new AtomicBoolean(true);
    private static final AtomicBoolean tooManyFilesFlag = new AtomicBoolean(false);
    //max to 6GB
    private static  String record_file="log.txt";
    private static final long MaxStorageSize = 6442450944L;
    private static final AtomicLong fileStorage = new AtomicLong(0);
    public static long lastTime=System.currentTimeMillis()/1000; 
    private static PrintWriter pw=null;
    //传文件，加到上传列表
    //path = 日期+topic+文件名
//    public static void add(File file, String path, String topic) {
//        add(file, WlanManager.device_name, path, topic);
//    }
//
//    public static void add(File file, String mac, String path, String topic) {
//        if (!file.exists())
//            return;
//        files.offer(new FileUnit(file, topic));
//        if (fileStorage.addAndGet(file.length()) > MaxStorageSize && tooManyFilesFlag.compareAndSet(false, true)) {
//            LogUtil.log_error("[-] Too many files to upload, cover old file.");
//            while (fileStorage.get() > (MaxStorageSize - MaxStorageSize / 4)) {
//                fileStorage.addAndGet(-Objects.requireNonNull(files.peek()).getFile().length());
//                Objects.requireNonNull(files.poll()).getFile().delete();
//            }
//            tooManyFilesFlag.set(false);
//        }
//    }


    public static HashSet<FileUnit> getFiles() {
        return files;
    }

    public static void addAllByPath(String path) {
            File[] fileNames = new File(path).listFiles();
            if (fileNames == null)
                return;
            for (File file : fileNames) {
                if(file.isDirectory())
                    continue;
                fileStorage.addAndGet(file.length());
                String fileName = file.getName();
                String[] components = fileName.split("_", 2);
                if (components.length != 2) {
                    System.out.println("发现格式异常的非法文件:" + fileName);
                    return;
                }
                String deviceName = components[0];
                String dataFileName = components[1];
                LocalDate date = LocalDate.now();
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                files.add(new FileUnit(file, "distributed/" + date.format(formatter) + "/"
                        + deviceName + "/" + dataFileName, deviceName));
            }
            System.out.println("[+] All file add to upload queue @" + path);
    }
    public static void log(String str){
	try {
        Date date = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date1 = formatter.format(date);
        FileOutputStream fos = new FileOutputStream(record_file,true);
        OutputStreamWriter osw = new OutputStreamWriter(fos);
        pw = new PrintWriter(osw);
        pw.println(str+"\n"+date1);
	}catch (FileNotFoundException e) {
        e.printStackTrace();
    }finally {
        pw.close();
    }
}
    public static void runTime()
    {
        try{
        long now=System.currentTimeMillis()/1000; 
        long runTime=now-lastTime;
        long hour=runTime/3600;
        long min=runTime/60;
        log("已运行"+Long.toString(hour)+"小时"+Long.toString(min)+"分钟");
        }catch(Exception e){
        e.printStackTrace();
        }
        
    }
    public static void start() throws IOException {
        // int index=0;
        // queue=new ConcurrentLinkedDeque<>();
        // FileUploader.InitUpload();
        try{
            new Thread(new Runnable() {

                @Override
                public void run() {
                    while(true)
                    {
                        // TODO Auto-generated method stub
                        runTime();
                        try{
                            Thread.sleep(300000);
                        }catch(Exception e){
                            e.printStackTrace();
                        }
                    }
                  
                }
                
              } ).start();
            //创建一个服务器端的Socket，即ServerSocket，绑定需要监听的端口
            
            while(true){//循环侦听新的客户端的连接
                FileUploader.receive();
                
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    public static void pause() {
        enableUpload.set(false);
    }

    public static void resume() {
        enableUpload.set(true);
    }

    public static void stop() {

        enableUpload.set(false);
        ThreadFlag.set(false);
    }

    

    private static String storageSize(long size) {
        if (size < 1024) {
            return size + "B";
        } else if (size < 1024 * 1024) {
            return size / 1024L + "KB";
        } else if (size < 1073741824L) {
            return size / 1048576L + "MB";
        } else
            return size / 1073741824L + "GB";
    }

    private static final AtomicBoolean ThreadFlag = new AtomicBoolean(true);
    private static Thread uploadThread;
}